//
//  BLPlayerControlView.swift
//  player_demo
//
//  Created by cgw on 2024/7/4.
//

import UIKit
import AVFAudio
import MediaPlayer

/*
 * player_demo        需注释： import DeviceRotation
 * BLPlayerFramework  需导入： import DeviceRotation
 */

#if BLPLAYER_FRAMEWORK
import DeviceRotation
#endif


fileprivate let NERSpring = "<-->"
fileprivate let ColorF = "#FFFFFF"
fileprivate let ColorF1 = "#F1F1F1"

protocol BLPlayerControlViewDelegate{
    func playerControlView(_ controlView: BLPlayerControlView, handlePlayBtn:UIButton)
    func playerControlView(_ controlView: BLPlayerControlView, handleBackBtn:UIButton)
    func playerControlView(_ controlView: BLPlayerControlView, handleRateBtn:UIButton)
    func playerControlView(_ controlView: BLPlayerControlView, handleFullScreenBtn:UIButton)
    
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderStart: UISlider)
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderEnd: UISlider)
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderOutEnd: UISlider)
    func playerControlView(_ controlView: BLPlayerControlView, handleSliderValueChange: UISlider)
    
    func playerControlView(_ controlView: BLPlayerControlView, getImageFromDuration duration: TimeInterval, complete:@escaping (UIImage)->Void)
    func playerControlView(_ controlView: BLPlayerControlView, updatePlayRate rate: Double)
}

class BLPlayerControlView: UIView {
    let backBtn = UIButton()
    let titleL = UILabel()
    let moreBtn = UIButton()
    let timeView = TimeView()
    let sliderView = BLPlayerTimeSlider()
    let rateBtn = BLSelectRateView.RateBtn()
    let fullscreenBtn = UIButton()
    fileprivate let playBtn = BLPlayerButton()
    fileprivate let bgView = BLPlayerControlBgView()
    
    var delegate: BLPlayerControlViewDelegate?
    
    var isDraggingSlider = false{
        didSet{
            self.bgView.isDraggingSlider = isDraggingSlider
        }
    }
    
    private let panModel = BLPlayerPanModel()
    
    // MARK: - Public
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.setupUI()
        self.addGestures()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupVideoTitle(_ title: String?) {
        self.titleL.text = title 
    }
    
    func setIsPlaying(_ isplaying: Bool) {
        self.playBtn.isSelected = isplaying
    }
    
    func setPlayTime(_ playbackTime: TimeInterval, totalTime: TimeInterval) {
   
        self.timeView.totalDuration = totalTime
        
        self.timeView.totalTimeL.text = totalTime.toHourMinSecond()
        self.timeView.currTimeL.text = playbackTime.toHourMinSecond()
        
        self.sliderView.value = Float(playbackTime/totalTime)
    }
        
    func showSelectRateView(_ currRate: Float, complete: @escaping (Float)->Void) {
        let rate = CGFloat(currRate)
        self.bgView.isHidden = true
        BLSelectRateView.show(inView: self, currRate: rate) { nrate in
            if let r = nrate, r != rate {
                complete(Float(r))
//                self.rateBtn.str("\(r)X")
                self.rateBtn.rate = Float(r)
                let msg = "已开启\(r)倍速播放"
                BLRateHUDView.shared.show(inView: self, text: msg, autoHide: true)

            }else{
                self.bgView.isHidden = false
            }
        }
    }
    
    // MARK: - TouchEvents
    
    @objc func handleBack() {
        delegate?.playerControlView(self, handleBackBtn: self.backBtn)
    }
    
    @objc func handleRate() {
        delegate?.playerControlView(self, handleRateBtn: self.rateBtn)
    }
    
    @objc func handlePlayBtn() {
        delegate?.playerControlView(self, handlePlayBtn: self.playBtn)
    }
    
    @objc func handleFullBtn() {
        print("点击全屏按钮")
        
        let isFullScreen = BLDeviceRotation.currOrientation().isLandscape
        BLDeviceRotation.interfaceOrientation(isFullScreen ? .portrait : .landscapeRight)
    }
    
    @objc func handleSliderStart() {
        self.isDraggingSlider = true
        self.panModel.dragType = .progress
        
        BLDragProgressPreviewView.shared.show(inView: self)
        
        delegate?.playerControlView(self, handleSliderStart: self.sliderView)
    }
    
    @objc func handleSliderEnd() {
        delegate?.playerControlView(self, handleSliderEnd: self.sliderView)
//        self.isDraggingSlider = false
        
        BLDragProgressPreviewView.shared.hide()
    }
    
    @objc func handleSliderOutEnd() {
        
        delegate?.playerControlView(self, handleSliderOutEnd: self.sliderView)
        
        self.isDraggingSlider = false
        
        BLDragProgressPreviewView.shared.hide()
    }
    
    @objc func handleSliderValueChange() {
        
        let tt = self.timeView.totalDuration
        let ct = tt*TimeInterval(self.sliderView.value)
        self.setPlayTime(ct, totalTime: tt)
        
        delegate?.playerControlView(self, handleSliderValueChange: self.sliderView)
        
        
        BLDragProgressPreviewView.shared.updateValue(progress: CGFloat(sliderView.value), totalTime: tt)
        
        self.delegate?.playerControlView(self, getImageFromDuration: ct, complete: { img in
            BLDragProgressPreviewView.shared.setupImage(img)
        })
    }
    
    // MARK: - 手势
//    var beginLocation: CGPoint?
    @objc func handleTap() {
        self.bgView.isHidden = !self.bgView.isHidden
    }
    
    @objc func handleLongPress(_ ges: UIGestureRecognizer) {
        if ges.state == .began {
            self.delegate?.playerControlView(self, updatePlayRate: 2.0)
            let msg = "2.0倍速播放中"
            BLRateHUDView.shared.show(inView: self, text: msg, autoHide: false)
            
            ///倍速播放开始1秒后，隐藏控制视图
            DispatchQueue.main.asyncAfter(deadline: .now()+1.0) {
                self.bgView.isHidden = true
            }
        }else if ges.state != .changed {
            
            self.delegate?.playerControlView(self, updatePlayRate: Double(self.rateBtn.rate))
            BLRateHUDView.shared.hide()
        }
    }
    
    @objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
        
        
        let translation = gestureRecognizer.translation(in: self)
        let location = gestureRecognizer.location(in: self)
        let state = gestureRecognizer.state
        if state == .began {
            self.panModel.beginLocation = location
            self.panModel.oriBrightness = UIScreen.main.brightness
            self.panModel.oriColumn = AVAudioSession.sharedInstance().outputVolume
            self.panModel.oriProgress = self.sliderView.value
        }
        
        ///若是左边缘滑动，则优先处理，退出播放器
        if handleLeftEdgePan(gestureRecognizer) {
            return;
        }
        
        ///若是屏幕中间部分，则优先处理，滑动退出手势
        if handleMiddleSlideDownPan(gestureRecognizer) {
            return;
        }
        
        guard let beginLocation = panModel.beginLocation else { return }
        
        let dy = location.y-beginLocation.y
        let dx = location.x-beginLocation.x
        
        //确定拖动的类型
        if state == .changed {
            // 计算滑动的距离
            let horizontalDistance = abs(translation.x)
            let verticalDistance = abs(translation.y)
            
            // 根据触摸点的位置判断滑动方向和左右区域
            let isInLeftScreen = location.x < self.bounds.width / 2
            
            let dragType = panModel.dragType
            ///确定拖动的类型
            if dragType == .notBegin {
                if verticalDistance < horizontalDistance {
                    panModel.dragType = .progress
                    self.isDraggingSlider = true
                    BLDragProgressPreviewView.shared.show(inView: self)
                }
                else if isInLeftScreen {
                    panModel.dragType = .brightness
                    BLBrightnessProgressView.shared.show(inView: self, isVolumn: false, value: Float(panModel.oriBrightness))
                }
                else {
                    panModel.dragType = .volumn
                    BLBrightnessProgressView.shared.show(inView: self, isVolumn: true, value: Float(panModel.oriColumn))
                }
            }
            
            
            self.handleBrightnessGesture(dy: dy, state: state)
            self.handleVolumnGesture(dy: dy, state: state)
            self.handleProgressGesture(dx: dx, state: state)
        }
        else if state == .ended || state == .failed || state == .cancelled{
            
            self.handleBrightnessGesture(dy: dy, state: state)
            self.handleVolumnGesture(dy: dy, state: state)
            self.handleProgressGesture(dx: dx, state: state)
            
            
            self.panModel.setupDefault()
        }
    }
    
    // MARK: - 手势下拉返回和左侧边缘滑动返回
    ///左边缘滑动手势，返回
    @objc func handleLeftEdgePan(_ gestureRecognizer: UIPanGestureRecognizer) -> Bool{
        let translation = gestureRecognizer.translation(in: self)
        let location = gestureRecognizer.location(in: self)
        
        let size = self.frame
        
        func isEdgeLeftPan() -> Bool{
            guard let bl = self.panModel.beginLocation else {
                return false
            }
            return bl.x < 40
        }
        
        let tx = translation.x
        switch gestureRecognizer.state {
        case .began:
            print("开始")
//            beginLocation = location
        case .changed:
            
//            let dx = location.x-(beginLocation?.x ?? 0.0)
            if isEdgeLeftPan() {
                
                self.getViewController()?.view.bl_x = tx
            }
        case .cancelled, .failed, .ended:
            if isEdgeLeftPan() {
                self.panModel.setupDefault()
                if let v = self.getViewController()?.view {
                    //向右拖动
                    
                    let viewWidth = self.frame.width
                    if tx > viewWidth/4.0 {
                        UIView.animate(withDuration: 0.3) {
                            v.bl_x = viewWidth
                        } completion: { fini in
                            self.getViewController()?.dismiss(animated: true, completion: nil)
                        }
                    }else{
                        UIView.animate(withDuration: 0.3) {
                            v.bl_x = 0
                        }
                    }
                }
            }
        case .possible:
            print("possible")
            break
        @unknown default:
            print("pan other state")
        }
        
        let isEdgeLeftPan = isEdgeLeftPan()
        return isEdgeLeftPan
    }
    
    ///屏幕中间下滑手势，退出控制器
    func handleMiddleSlideDownPan(_ gestureRecognizer: UIPanGestureRecognizer) -> Bool{
        let translation = gestureRecognizer.translation(in: self)
        let location = gestureRecognizer.location(in: self)
        
        let size = self.frame
        
        //垂直方向的下滑
        func isMiddlePan() -> Bool{
            guard let bl = self.panModel.beginLocation else {
                return false
            }
            
//            return bl.y < size.height/5.0;
            
            return (size.width/3.0 < bl.x) && (bl.x < size.width/3.0*2.0) && bl.y < size.height/4.0
        }
        
        let ty = translation.y
        switch gestureRecognizer.state {
        case .began:
            print("开始")
//            beginLocation = location
        case .changed:
            
//            let dx = location.x-(beginLocation?.x ?? 0.0)
            if isMiddlePan() {
                self.getViewController()?.view.bl_y = ty
            }
        case .cancelled, .failed, .ended:
            if isMiddlePan() {
//                beginLocation = nil
                self.panModel.setupDefault()
                if let v = self.getViewController()?.view {
                    //向下拖动
                    
                    let viewHeight = self.frame.height
                    if ty > viewHeight/4.0 {
                        UIView.animate(withDuration: 0.3) {
                            v.bl_y = viewHeight
                        } completion: { fini in
                            self.getViewController()?.dismiss(animated: true, completion: nil)
                        }
                    }else{
                        UIView.animate(withDuration: 0.3) {
                            v.bl_y = 0
                        }
                    }
                }
            }
        case .possible:
            print("possible")
            break
        @unknown default:
            print("pan other state")
        }
        
        let isMiddlePan = isMiddlePan()
        return isMiddlePan
    }
    
//    private func getCtrlView() -> UIView? {
//        let vc = self.getViewController()
//        if let svc = vc?.parent as? BLPlayer {
//            return svc.view
//        }
//        return vc?.view
//    }
    
    // MARK: - 亮度、音量、拖动快进
    func handleVolumnGesture(dy: Double, state: UIGestureRecognizer.State) {
        if panModel.dragType != .volumn {
            return
        }
        
        if state != .changed {
            BLBrightnessProgressView.shared.hide()
            return;
        }
        
        // 调整音量
        let size = self.bounds.size
        let currentVolume = self.panModel.oriColumn
        let adjustedVolume = currentVolume - Float(dy / size.height * 2.0)
        
        if panModel.volumeView == nil {
            let volumeView = MPVolumeView()
            // 添加音量视图，用于调整音量
            volumeView.frame = CGRect(x: -100, y: -100, width: 10, height: 10)
            self.addSubview(volumeView)
            
            panModel.volumeView = volumeView
        }
        let slider = panModel.volumeView?.subviews.first(where: { $0 is UISlider }) as? UISlider
        slider?.value = adjustedVolume
        
        BLBrightnessProgressView.shared.setValue(adjustedVolume)
    }
    
    func handleBrightnessGesture(dy: Double, state: UIGestureRecognizer.State) {
        if panModel.dragType != .brightness {
            return
        }
        
        if state != .changed {
            BLBrightnessProgressView.shared.hide()
            return;
        }
        
        let size = self.bounds.size
        let currentBrightness = panModel.oriBrightness
        let adjustedBrightness = currentBrightness - (dy / size.height * 2.0)
        UIScreen.main.brightness = max(0.0, min(1.0, adjustedBrightness))
        BLBrightnessProgressView.shared.setValue(Float(adjustedBrightness))
    }
    
    func handleProgressGesture(dx: Double, state: UIGestureRecognizer.State) {
        if panModel.dragType != .progress {
            return
        }
   
        if state == .ended {
            self.delegate?.playerControlView(self, handleSliderEnd: self.sliderView)
            BLDragProgressPreviewView.shared.hide()
        }
        else if state == .changed {
            guard let oldProgress = panModel.oriProgress else {
                return
            }
            
            let totalTime = self.timeView.totalDuration
            let oldTime = totalTime*TimeInterval(oldProgress)
            var toSec = oldTime + TimeInterval(dx/3.0) //每滑动3个点，增加1秒

            toSec = min(totalTime, toSec)
            sliderView.value = Float(toSec/totalTime);
            
            self.timeView.currTimeL.text = TimeInterval(toSec).toHourMinSecond()
            
            self.setPlayTime(toSec, totalTime: totalTime)
            
            BLDragProgressPreviewView.shared.updateValue(progress: CGFloat(sliderView.value), totalTime: totalTime)
            
            self.delegate?.playerControlView(self, getImageFromDuration: toSec, complete: { img in
                BLDragProgressPreviewView.shared.setupImage(img)
            })
        }
    }
    
    // MARK: - 添加手势
    func addGestures() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        self.addGestureRecognizer(tap)
        
        let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(handleLongPress))
        self.addGestureRecognizer(longPress)
        
        //音量、亮度、快进 滑动调整
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        panGesture.delegate = self
        self.addGestureRecognizer(panGesture)
    }
    
    // MARK: - SetupUI
    func setupUI() {
        bgView.bg("#000,0.3").embedIn(self)
        bgView.isHidden = true
        bgView.isHidden = false
        
        backBtn.img(self.image("blplayer_close")).pin(.wh(50, 50))
        backBtn.imageView?.pin(.wh(25, 25))
        
        titleL.font("15").color(ColorF).pin(.h(50))
        
        moreBtn.font(13).pin(.wh(50, 50)).color(ColorF)
//        let ig = UIImage.init(named: "list_w")// "home_list")
//        moreBtn.img(ig).imageView?.pin(.wh(26, 24))
//        moreBtn.setImage(ig?.withTintColor(ColorMain), for: .highlighted)
//        moreBtn.isHidden = true
        
        let topView = HStack(10,backBtn,NERSpring,titleL,NERSpring,moreBtn,10)
        topView.pin(.h(50.0)).addTo(bgView).makeCons { make in
            make.left.right.equal(0)
            make.top.equal(10.0)
        }
        
        
        ///底部视图
        timeView.pin(.lowResistance)
        sliderView.maximumValue = 1.0
        sliderView.minimumValue = 0.0
        sliderView.setThumbImage(self.image("blplayer_slider_thumb"), for: .normal)
        sliderView.minimumTrackTintColor = .white
        sliderView.maximumTrackTintColor = .init(white: 0.5, alpha: 0.5)
        sliderView.pin(.h(50),.lowResistance)
        sliderView.addTarget(self, action: #selector(handleSliderValueChange), for: .valueChanged)
        sliderView.addTarget(self, action: #selector(handleSliderEnd), for: .touchUpInside)
        sliderView.addTarget(self, action: #selector(handleSliderOutEnd), for: .touchUpOutside)
        sliderView.addTarget(self, action: #selector(handleSliderStart), for: .touchDown)
        
        rateBtn.pin(.wh(50, 45)).font(12).color(ColorF).str("倍速")
        
        fullscreenBtn.pin(.wh(50, 45)).img(self.image("blplayer_fullscreen"))
        let bottomView = HStack(10,timeView,10.0,sliderView,10.0,rateBtn,fullscreenBtn,10)
        bottomView.pin(.h(50)).addTo(bgView).makeCons { make in
            make.left.right.bottom.equal(0)
        }
        
        ///播放按钮
        playBtn.img(self.image("blplayer_play")).pin(.wh(165, 165)).addTo(bgView).makeCons { make in
            make.centerY.centerX.equal(bgView)
        }
        playBtn.setImage(self.image("blplayer_pause"), for: .selected)
        playBtn.layoutBlock = { size, btn in
            let w: CGFloat = 40.0
            btn.imageView?.frame = .init(x: size.width/2.0-w/2.0, y: size.height/2.0-w/2.0, width: w, height: w)
        }
        playBtn.imageView?.mode(.scaleAspectFill)
        playBtn.alpha = 0.5
        
        //事件
        fullscreenBtn.addTarget(self, action: #selector(handleFullBtn), for: .touchUpInside)
        backBtn.addTarget(self, action: #selector(handleBack), for: .touchUpInside)
        rateBtn.addTarget(self, action: #selector(handleRate), for: .touchUpInside)
        playBtn.addTarget(self, action: #selector(handlePlayBtn), for: .touchUpInside)
    }
}


extension BLPlayerControlView: UIGestureRecognizerDelegate{
    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let gestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else {
            return true
        }
        
        //是否应该响应拖动手势
        let translation = gestureRecognizer.translation(in: self)
        let location = gestureRecognizer.location(in: self)
        let frame = self.frame
        
        ///若正在显示控制视图，则距离屏幕下方150的区域 不可响应
        if self.bgView.isHidden == false {
            if translation.y > self.frame.height-150 {
                return false
            }
        }
        
        return true
    }
}

// MARK: -
// MARK: - SubClasses
// MARK: -

fileprivate enum DragType: Int{
    case notBegin = 0    //未开始
    case brightness = 1  //亮度
    case volumn = 2      //音量
    case progress = 3    //进度
}

fileprivate class BLPlayerPanModel: NSObject{
    
    var beginLocation: CGPoint?
    var dragType: DragType = .notBegin
    var oriBrightness: CGFloat = 0.0
    var oriColumn: Float = AVAudioSession.sharedInstance().outputVolume
    var oriProgress: Float?
    
    var volumeView: MPVolumeView?
    
    func setupDefault() {
        beginLocation = nil
        dragType = .notBegin
        oriBrightness = 0.0
        oriColumn = AVAudioSession.sharedInstance().outputVolume
        oriProgress = nil
        volumeView?.removeFromSuperview()
        volumeView = nil
    }
}

///时间
class TimeView: UIView{
    let currTimeL = UILabel()
    let totalTimeL = UILabel()
    let midL = UILabel()
    
    var totalDuration : TimeInterval = 0.0
    override init(frame: CGRect) {
        super.init(frame: frame)
        midL.color(ColorF).str("/")
        currTimeL.color(ColorF).str("00:00")
        totalTimeL.str("00:00")
        totalTimeL.textColor = .init(white: 1.0, alpha: 0.7)
        
        self.updateFontSize(size: 13)
        
        HStack(currTimeL,3.0,midL,3.0,totalTimeL).embedIn(self).align(.center)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func updateFontSize(size: CGFloat, isBold: Bool = false) {
        // 创建数字等宽字体
        let monospacedFont = UIFont.monospacedDigitSystemFont(ofSize: size, weight: .regular)
        totalTimeL.font = monospacedFont
        currTimeL.font = UIFont.monospacedDigitSystemFont(ofSize: size, weight: isBold ? .medium : .regular)
        midL.font = monospacedFont
    }
}

///进度滑块
class BLPlayerTimeSlider: UISlider {
    override open func trackRect(forBounds bounds: CGRect) -> CGRect {
        let trackHeight: CGFloat = 2
        let position = CGPoint(x: 0, y: 24)
        let customBounds = CGRect(origin: position, size: CGSize(width: bounds.size.width, height: trackHeight))
        super.trackRect(forBounds: customBounds)
        return customBounds
    }
    
    override open func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
        let rect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
        let newx = rect.origin.x - 10
        let newRect = CGRect(x: newx, y: 0, width: 30, height: 50)
        return newRect
    }
}

class BLRateHUDView: UIView{
    
    static let shared = BLRateHUDView()
    
    var text: String?{
        didSet{
            self.textL.text = text;
        }
    }
    private let textL = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        textL.font(12).color(ColorF)
        
        HStack(textL).embedIn(self,0,15)
        
        self.backgroundColor = .init(white: 0, alpha: 0.3)
        
        let h: CGFloat = 28.0
        self.pin(.h(h)).radius(h/2.0)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func show(inView: UIView, text: String, autoHide: Bool) {
        self.text = text
        self.removeFromSuperview()
        self.addTo(inView).makeCons { make in
            make.centerX.equal(inView)
            make.top.equal(50)
        }
        
        if autoHide {
            DispatchQueue.main.asyncAfter(deadline: .now()+1.5) {
                self.hide()
            }
        }
    }
    
    func hide() {
        self.removeFromSuperview()
    }
}

///亮度和音量视图
class BLBrightnessProgressView: UIView {
    private let imgView = UIImageView()
    private let progressView = UIProgressView()
    
    static let shared = BLBrightnessProgressView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        imgView.pin(.wh(16, 16)).mode(.scaleAspectFit)
        progressView.pin(.h(3.0),.lowResistance)
        progressView.trackTintColor = .init(white: 1.0, alpha: 0.5)
        progressView.tintColor = .white
        
        HStack(imgView,10,progressView).embedIn(self,0,15).align(.center)
        
        self.backgroundColor = .init(white: 0, alpha: 0.5)
        self.pin(.wh(210,30)).radius(15.0)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setValue(_ value: Float) {
        self.progressView.progress = value
    }
    
    func show(inView: UIView, isVolumn:Bool, value: Float)  {
        let img = isVolumn ? "blplayer_volumn" : "blplayer_bright"
        self.imgView.image = self.image(img)
        
        self.progressView.progress = value
        
        self.removeFromSuperview()
        self.addTo(inView).makeCons { make in
            make.top.equal(60)
            make.centerX.equal(inView)
        }
    }
    
    func hide() {
        self.removeFromSuperview()
    }
}

///拖动时进度预览图片视图
class BLDragProgressPreviewView: UIView {
    let imgView = UIImageView()
    let timeView = TimeView()
    
    static let shared = BLDragProgressPreviewView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let w: CGFloat = 324.0/2.0
        let h: CGFloat = 184.0/2.0
        imgView.pin(.wh(w, h)).border(1.0, "#FFF").radius(5.0)
        imgView.mode(.scaleAspectFit)
        
        imgView.backgroundColor = .black
        timeView.backgroundColor = .clear
        timeView.pin(.h(20))
        timeView.updateFontSize(size: 15, isBold: true)
        
        let tv = HStack(10,timeView,10).pin(.h(26)).radius(13.0).align(.center)
        tv.backgroundColor = .init(white: 0, alpha: 0.5)
        
        VStack(NERSpring,imgView,10,tv,10).embedIn(self).align(.center)
        
        self.backgroundColor = .clear
        self.pin(.wh(w,h+50))
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func show(inView: UIView) {
//        return;
        self.hide()
        self.addTo(inView).makeCons { make in
            make.centerX.equal(inView)
            make.bottom.equal(-60)
        }
    }
    
    func hide() {
        
        self.removeFromSuperview()
        self.imgView.image = nil
    }
    
    func setupImage(_ img: UIImage) {
        if self.superview != nil {
            self.imgView.image = img
        }
    }
    
    func updateValue(progress: CGFloat, totalTime: TimeInterval ) {

//        guard let player = manager as? VLCMediaPlayer else {
//            return
//        }
//        
//        guard let totalTime = player.media?.length.intValue else {
//            return
//        }
        
        //目标时间
        let tTime = totalTime ////CGFloat(totalTime)/CGFloat(1000.0)
        let toSecond = progress*tTime
        
        self.timeView.totalTimeL.text = TimeInterval(tTime).toHourMinSecond()
        self.timeView.currTimeL.text = TimeInterval(toSecond).toHourMinSecond()
        
//        if let ul = player.media?.url {
//            let ass = AVURLAsset.init(url:ul)
//            let img = self.getVideoCurrentImage(second: toSecond, avAsset: ass)
//            self.imgView.image = img
//        }
    }
    
    /// 获取视频的关键图片
    ///
    /// - Returns: 第几秒的图片
    func getVideoCurrentImage(second:Double, avAsset: AVURLAsset?) -> UIImage? {
        guard let avAsset = avAsset else {
            return nil
        }
        let generator = AVAssetImageGenerator(asset: avAsset)
        generator.appliesPreferredTrackTransform = true
        let time = CMTimeMakeWithSeconds(second, preferredTimescale: 600)
        var actualTime:CMTime = CMTimeMake(value: 0,timescale: 0)
        do {
            let imageRef:CGImage = try generator.copyCGImage(at: time, actualTime: &actualTime)
            let currentImage = UIImage(cgImage: imageRef)
            
            return currentImage
        } catch  {
            
        }
        return nil
    }
}

///倍速
class BLSelectRateView: UIView,UITableViewDataSource,UITableViewDelegate {
    let tableView = UITableView()
    
    var datas: [RateModel]?
    var handleBlock: ((CGFloat?)->Void)?
    var currRate: Float?
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let effectView = UIVisualEffectView.init(effect: UIBlurEffect(style: .dark))
        effectView.embedIn(self)
        
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(RateCell.self, forCellReuseIdentifier: "cell")
        tableView.rowHeight = 50
        tableView.separatorStyle = .none
        tableView.backgroundColor = .clear
        effectView.contentView.addSubview(self.tableView)
        
        self.backgroundColor = .init(white: 0, alpha: 0.1)
        self.clipsToBounds = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        tableView.frame = self.bounds
    }
    
    // MARK: - Public
    static func show(inView: UIView, currRate: CGFloat, handleBlock:@escaping (CGFloat?)->Void) {
        let fr = inView.bounds
        let bgView = UIButton()
        bgView.backgroundColor = .init(white: 0, alpha: 0.1)
//        bgView.frame = fr
//        bgView.addTo(inView)
        
        guard let v = inView.getViewController()?.view else {
            return
        }
        
        //UIApplication.shared.keyWindow!
//        bgView.addTo(v)
        bgView.embedIn(v)
        
        let isFullScreen = fr.width > fr.height
        let rateView = BLSelectRateView()
        let w: CGFloat = isFullScreen ? 120 : 100
        let h: CGFloat = isFullScreen ? fr.height-50.0 : 300.0
        rateView.pin(.wh(w, h)).addTo(bgView).makeCons { make in
            make.bottom.equal(-25)
            make.right.equal(-25)
        }
        rateView.radius(10.0)
        rateView.handleBlock = handleBlock
        rateView.loadDatas(selectedRate: currRate)
        bgView.addTarget(rateView, action: #selector(handleBgView), for: .touchUpInside)
        rateView.clipsToBounds = true
    }
    
    @objc func handleBgView() {
        self.handleBlock?(nil)
        self.hide()
    }
    
    func hide() {
        self.superview?.removeFromSuperview()
    }
    
    // MARK: - LoadDatas
    func loadDatas(selectedRate: CGFloat) {
        var ar = [RateModel]()
        let rates = [0.5,0.75,1.0,1.25,1.5,2.0]
        for r in rates.reversed() {
            let m = RateModel()
            m.rate = r
            m.rateText = "\(r)X"
            if r == 1.0 {
                m.rateText = "\(r)X (正常)"
            }
            m.isSelected = Int(r*100.0) == Int(selectedRate*100.0)
            ar.append(m)
        }
        self.datas = ar
        self.tableView.reloadData()
    }
    
    // MARK: - Delegate
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.datas?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let c = self.datas?.count ?? 0
        if c > indexPath.row {
            (cell as? RateCell)?.model = datas?[indexPath.row]
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        if let datas = datas, datas.count > indexPath.row {
            self.handleBlock?(datas[indexPath.row].rate)
        }
        
        self.hide()
    }
    
    class RateCell: UITableViewCell {
        
        let rateL = UILabel()
        var model: RateModel?{
            didSet{
                rateL.text = model?.rateText
                if model?.isSelected == true {
                    rateL.color(ColorF).font("15")
                }else{
                    rateL.color(ColorF1).font(13)
                }
            }
        }
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            
            rateL.font(13).color(ColorF1).align(.center)
            
            let v = HStack(NERSpring,rateL,NERSpring).embedIn(contentView).align(.center)
            v.isUserInteractionEnabled = false
            
            self.selectionStyle = .none
            self.contentView.backgroundColor = .clear
            self.backgroundColor = .clear
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class RateModel: NSObject {
        var rate: CGFloat = 1.0
        var rateText: String?
        var isSelected = false
    }
    
    class RateBtn: UIButton{
        var rate: Float = 1.0{
            didSet{
                self.str("\(rate)X")
            }
        }
    }
}


/*
设置或返回View的 x y h w
*/
private extension UIView{
    var bl_h: CGFloat{
        get{
            return self.frame.height
        }
        set{
            var fr = self.frame
            fr.size.height = newValue
            self.frame = fr
        }
    }
    
    var bl_w: CGFloat{
        get{return self.frame.width}
        set{
            var fr = self.frame
            fr.size.width = newValue
            self.frame = fr
        }
    }
    
    var bl_x: CGFloat{
        get{return self.frame.minX}
        set{
            var fr = self.frame
            fr.origin.x = newValue
            self.frame = fr
        }
    }
    
    var bl_y: CGFloat{
        get{return self.frame.minY}
        set{
            var fr = self.frame
            fr.origin.y = newValue
            self.frame = fr
        }
    }
    
    var bl_cx: CGFloat{
        get{return self.center.x}
        set{
            self.center.x = newValue
        }
    }
    
    var bl_cy: CGFloat{
        get{return self.center.y}
        set{
            self.center.y = newValue
        }
    }
}

fileprivate class BLPlayerButton: UIButton {
    
    public var layoutBlock:((CGSize,UIButton)->Void)?
    
    public override func layoutSubviews() {
        super.layoutSubviews()
        
        layoutBlock?(self.frame.size,self)
    }
}


fileprivate class BLPlayerControlBgView: UIView{
    
    //自动隐藏
    var timer: Timer?
    var isDraggingSlider = false{
        didSet{
            if isDraggingSlider {
                self.invalidateTimer()
            }else{
                self.setupTimer()
            }
        }
    }
    
    override var isHidden: Bool{
        didSet{
            super.isHidden = isHidden
            if isHidden == false {
                self.setupTimer()
            }
            else {
                self.invalidateTimer()
            }
        }
    }
    
    func setupTimer() {
        self.invalidateTimer()
        weak var ws = self
        //5秒自动隐藏控制视图
        timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false, block: { ti in
            ws?.isHidden = true
        })
    }
    
    func invalidateTimer() {
        if let ti = timer {
            ti.invalidate()
            timer = nil
        }
    }
}


fileprivate extension NSObject {
    func image(_ name: String?) -> UIImage? {
        
        guard let n = name else {
            return nil
        }
        
//        return UIImage.init(named: n)
        
        return UIImage(named: n, in: Bundle(for: type(of: self)), compatibleWith: nil)
    }
}

fileprivate extension TimeInterval {
    
    func toHourMinSecond() -> String{
        let sec = Int(self)
        ///时分秒
        let s = sec%60
        let m = sec/60%60
        let h = sec/60/60
        var ti = String.init(format: "%02d:%02d", m,s)
        if h > 0 {
            ti = String.init(format: "%02d:\(ti)", h)
        }
        return ti
    }
}

fileprivate extension UIView{
    
    func currViewController() -> UIViewController? {
        return self.getViewController()
    }
    
    func getViewController()->UIViewController?{
        var next:UIView? = self
        repeat{
            if let nextResponder = next?.next{
                if(nextResponder.isKind(of: UIViewController.self)){
                    if let v = nextResponder as? UIViewController {
                        if let sv = v.parent as? BLPlayer {
                            return sv
                        }
                    }
                    return (nextResponder as! UIViewController)
                }
            }
            next = next?.superview
        }while next != nil
        return nil
    }
}

